package com.base.components.database.mybatis.configuration;

import com.base.components.common.service.database.DatabaseExecutor;
import com.base.components.database.mybatis.service.MybatisDatabaseExecutor;
import com.base.components.database.mybatis.service.PaginationJdbcTemplate;
import com.base.components.transaction.TransactionManager;
import com.github.pagehelper.autoconfigure.PageHelperProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;

import javax.sql.DataSource;

/**
 * MybatisConfiguration - 继承该配置类，并使用如下注解
 * <pre>
 *   {@code
 *      @EnableTransactionManagement
        @Configuration
        @tk.mybatis.spring.annotation.MapperScan("com.xx.xx.database.mybatis.mapper")
 *   }
 * </pre>
 *
 * @author <a href="morse.jiang@foxmail.com">JiangWen</a>
 * @version 1.0.0, 2018/6/5 0005 10:31
 */
public class MybatisConfiguration {
  @Autowired
  private DataSource dataSource;

  @Bean("paginationJdbcTemplate")
  public PaginationJdbcTemplate paginationJdbcTemplate(PageHelperProperties pageHelperProperties, JdbcTemplate jdbcTemplate){
    return new PaginationJdbcTemplate(pageHelperProperties, jdbcTemplate);
  }

  @Bean
  @ConditionalOnProperty(name = "base.rpc.tx.lcn.enable", havingValue = "false", matchIfMissing = true)
  public PlatformTransactionManager mybatisTransactionManager() {
    return new DataSourceTransactionManager(dataSource);
  }

  @Bean
  @ConditionalOnProperty(name = "base.rpc.tx.lcn.enable", havingValue = "true")
  public PlatformTransactionManager mybatisLcnTransactionManager() {
    return new DataSourceTransactionManagerExtend(dataSource);
  }

  @Bean
  @ConditionalOnMissingBean
  public DatabaseExecutor mybatisDatabaseExecutor(){
    return new MybatisDatabaseExecutor();
  }

  public static class DataSourceTransactionManagerExtend extends DataSourceTransactionManager {
    private static final long serialVersionUID = -3000903184426665785L;
    public DataSourceTransactionManagerExtend() {
    }
    public DataSourceTransactionManagerExtend(DataSource dataSource) {
      super(dataSource);
    }
    @Override
    protected void doCommit(DefaultTransactionStatus status) {
      TransactionManager.transactionManagerDoSuperCommit(new Runnable(){
        @Override
        public void run() {
          DataSourceTransactionManagerExtend.super.doCommit(status);
        }
      }, status);
    }
    @Override
    protected void doRollback(DefaultTransactionStatus status) {
      TransactionManager.transactionManagerDoSuperRollback(new Runnable() {
        @Override
        public void run() {
          DataSourceTransactionManagerExtend.super.doRollback(status);
        }
      }, status);
    }
  }
}
